package com.squirrel.auxiliary.typeconversion;

import com.alibaba.fastjson.util.TypeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;

/**
 * Oracle数据库类型转换
 *
 * @author wangyan
 */
@Component
public class PgTypeConversion implements TypeConversion {

    private static final Logger log = LoggerFactory.getLogger(PgTypeConversion.class);

    @Override
    public void dataConversion(PreparedStatement ps, String columnType, Map<String, Object> dataMedium, String inputField, int i) throws Exception {
        Object fieldVal = dataMedium.get(inputField);
        if (null == fieldVal || "".equals(fieldVal) || "null".equals(fieldVal) || "NULL".equals(fieldVal)) {
            ps.setNull(i + 1, Types.NULL);
            return;
        }
        if (columnType.contains("char")) {
            String typeName = dataMedium.get(inputField).getClass().getTypeName();
            if ("java.lang.Integer".equalsIgnoreCase(typeName) ||
                    "java.lang.Long".equalsIgnoreCase(typeName) ||
                    typeName.contains("json")) {
                //char类型客户端直接输入(1或者0)Integer类型转String
                String date = TypeUtils.castToString(dataMedium.get(inputField));
                ps.setString(i + 1, date);
            } else {
                ps.setString(i + 1, (String) dataMedium.get(inputField));
            }
        } else if (columnType.contains("int2")) {
            ps.setInt(i + 1, TypeUtils.castToInt(dataMedium.get(inputField)));
        } else if (columnType.contains("int4")) {
            ps.setInt(i + 1, TypeUtils.castToInt(dataMedium.get(inputField)));
        } else if (columnType.contains("int8")) {
            ps.setLong(i + 1, TypeUtils.castToLong(dataMedium.get(inputField)));
        } else if (columnType.contains("numeric")) {
            ps.setBigDecimal(i + 1, TypeUtils.castToBigDecimal(dataMedium.get(inputField)));
        } else if (columnType.contains("float4")) {
            ps.setFloat(i + 1, TypeUtils.castToFloat(dataMedium.get(inputField)));
        } else if (columnType.contains("float8")) {
            ps.setDouble(i + 1, TypeUtils.castToDouble(dataMedium.get(inputField)));
        } else if (columnType.contains("bool")) {
            ps.setBoolean(i + 1, TypeUtils.castToBoolean(dataMedium.get(inputField)));
        } else if (columnType.contains("timestamp")) {
            if ("java.time.Instant".equalsIgnoreCase(dataMedium.get(inputField).getClass().getTypeName())) {
                Date caseInstantDate = Date.from((Instant) dataMedium.get(inputField));
                Date date = TypeUtils.castToDate(caseInstantDate);
                ps.setTimestamp(i + 1, new Timestamp(date.getTime()));
            } else if ("java.sql.Timestamp".equalsIgnoreCase(dataMedium.get(inputField).getClass().getTypeName())) {
                //将从数据库查出来的Timestamp数据类型，直接入库
                ps.setTimestamp(i + 1, (Timestamp) dataMedium.get(inputField));
            } else if ("java.time.LocalDateTime".equalsIgnoreCase(dataMedium.get(inputField).getClass().getTypeName())) {
                LocalDateTime localDateTime = (LocalDateTime) dataMedium.get(inputField);
                Timestamp timestamp = Timestamp.valueOf(localDateTime);
                ps.setTimestamp(i + 1, timestamp);
            } else {
                Date date = TypeUtils.castToDate(dataMedium.get(inputField));
                ps.setTimestamp(i + 1, new Timestamp(date.getTime()));
            }
        } else if (columnType.contains("date")) {
            LocalDate localDate;
            if ("java.sql.Date".equalsIgnoreCase(dataMedium.get(inputField).getClass().getTypeName())) {
                java.sql.Date date = (java.sql.Date) dataMedium.get(inputField);
                localDate = date.toLocalDate();
            } else {
                localDate = (LocalDate) dataMedium.get(inputField);
            }
            ps.setDate(i + 1, java.sql.Date.valueOf(localDate));
        } else {
            log.error("PLSQL:{}数据类型还不能处理，请联系开发。", columnType);
        }
    }
}
